'''
@author: adi
'''
import operator
import os
from sets import Set


import numpy

from  nodeseq import nodeSeq
from nodeprog import nodeProg
from edge import Edge

dictionary = {} #{'t3': [('NO DIAGNOSIS ', 0.43333333333333335), ('THE . . . . . . DIAGNOSIS ', 0.29333333333333333)]}
seqFreqDic = {} #key-seq, value-amount of programs     # i.e. {'THERE WAS ': 2, 'THE . . . DIAGNOSIS ': 2}
listNodeSeq = []
listNodeProg = []
listEdge = []

MAXSEQLENGTH = 10
MAXSEQPREDICT = 1000
SETUPLENGTH = 10
ANOMALYRATE = 0.5 #Predicted seq divided real sequence amount

###input:inputfile,outputfile,minseqlength,maxseqlength,minrepetition
###output: 0 or 1
def inputcheck(inputfile,outputfile,minseqlength,maxseqlength,minrepetition):

    if None == inputfile or None == outputfile or None == minseqlength or None == maxseqlength or None == minrepetition :
        return 0
    if minseqlength < 1 or maxseqlength < minseqlength or minrepetition <2:
        return 0
    return 1

def findSeq(seq):
    for a in listNodeSeq:
        if ((nodeSeq)(a)).seq == seq:
            return seq
    return None

def exctractSeq(filename, countwordinfile):
    f = open(filename)
    lines = f.readlines()
    f.close()
    
    prog = nodeProg(countwordinfile)
    filelist={}
    lines = lines[5:]
    for line in lines:
        seqnode = None
        l = line.split()
        repetition = l[1]
        l = l[2:]
        seqFreq = ((float(repetition)) / ((countwordinfile)/len(l)))
        
        seq = " ".join(l)
     #   for word in l:
     #      seq += word + " "
        if not seq in seqFreqDic:
       # if None == seqFreqDic.get(seq): #new seq in the system
            seqFreqDic[seq] = 1
            seqnode = nodeSeq(seq,len(l)) 
            listNodeSeq.append(seqnode)   
        else:
            seqFreqDic[seq] +=1
            seqnode = findSeq(seq) #find sequence in seq list
            
        edge = Edge(seqFreq,repetition,prog,seqnode)
        
        if None != seqnode and None != edge :
            seqnode.connedge.append(edge)

            
        prog.connedge.append(edge)
        listEdge.append(edge)
        filelist[seq] = seqFreq
            

    listNodeProg.append(prog)
    sorted_filelist = sorted(filelist.items(), key=lambda x:x[1] ,reverse=True)
    dictionary[filename[:-4]] = sorted_filelist
    print (dictionary)

def createSeq(inputfile,outputfile,minseqlength,maxseqlength,minrepetition):    
    if(inputcheck(inputfile,outputfile,minseqlength,maxseqlength,minrepetition) == 0 ):
        command = "teiresias_TW.exe -l"+str(minseqlength)+" -w"+str(maxseqlength)+" -k"+str(minrepetition)+" -i"+str(inputfile)+" -o"+str(outputfile)
        success = os.system(command)
        if success == 0:
            return True
    return False

def countWordsInfile(filename):
    f = open(filename,"r+")
    count = len(f.read().split())
    f.close()
    return count

def exctractSeqforNewFile(outputfile): #return list of sequence appear in the file
    f = open(outputfile)
    lines = f.readlines()
    f.close()
    
    seqlist=[]
    lines = lines[5:]
    for line in lines:
        l = line.split()
        l = l[2:]
        seq = ""
        for word in l:
            seq += word + " "
        seqlist.append(seq)
        
        return seqlist

def processinputfile(filepath): #take the input file and double it
    f = open(filepath)
    lines = f.readlines()
    f.close()
    f = open(filepath,'w')
    for line in lines:
        f.write(str(line)+'\n')
        f.write(str(line)+'\n')
    f.close()

def exctractListOfSeq(inputfile):
    outfile  = inputfile[:-4]+".txt"
    listOfSeq = None
    if createSeq(inputfile,outfile,1,MAXSEQLENGTH,2) : #default 2 2 2
            listOfSeq = exctractSeqforNewFile(inputfile)  
    return listOfSeq

def removeUslessSeq(): #remove sequence that connected to all nodes in listNodeProg
    sizeOfNodeProgList = len(listNodeProg)
    
    for seqNode in listNodeSeq:
        if seqNode.connedge == sizeOfNodeProgList: #remove node
            seq = seqNode.seq
            for edgeprog in seqNode.connedge:
                try:
                    if(len(edgeprog.nodeprog.connedge) > 1):
                        edgeprog.nodeprog.connedge.remove(edgeprog)
                        listEdge.remove(edgeprog)
                        seqNode.connedge.remove(edgeprog)
                        seqNode.remove = True
                except :
                    continue
                
    for seqNode in listNodeSeq:
        if seqNode.remove :
            try:
                listNodeSeq.remove(seqNode)
            except :
                continue            
    
def linkPrediction(listOfSeq):#return list of sequence prediction- list of object nodeSeq
    listOfEdgePrediction = []
    listOfSeqPrediction = [] #list of object nodeseq
    size = 0
    
    for knownSeq in listNodeSeq:
        for unknownSeq in listOfSeq:
            if (((nodeSeq)(knownSeq)).seq) == unknownSeq : #exctract list of relevent edge
                listOfEdgePrediction.append(((nodeSeq)(knownSeq)).connedge)
    for knownedge in listOfEdgePrediction:
        if None == knownedge:
            continue
        if size > MAXSEQLENGTH:
            break
        listOfSeqPrediction.extend(((nodeProg)(((Edge)(knownedge)).nodeprog)).connedge)
        size +=1
        
    return listOfSeqPrediction
                    
def getNormalityRate(predictSeqList,realSeqList): #output-normality rate range[0,1]
    countPredicted = 0
    
    for realSeq in realSeqList:
        for predictSeq in predictSeqList:
            if realSeq.seq == predictSeq.seq:
                countPredicted+=1
                break
                
    sizeRealSeqList = len(realSeqList)            
    return (((float)(countPredicted))/sizeRealSeqList)
    
def run(inputfile): #prediction phase
    processinputfile(inputfile) #double input file
    listOfSeq = exctractListOfSeq(inputfile)
    predictSeqList = linkPrediction(listOfSeq)
    
    
###input: predictSeqList- list of nodeSeq object
###       realSeqList- list of string
###output: list of equal sequence- list of nodeSeq object (only equal! seq...)

def comparePredictSeqAndRealSeq(predictSeqList, realSeqList): 
    listOfEqualSeq =[]
    for predictSeqObj  in predictSeqList:
        if ((nodeSeq)(predictSeqObj)).seq in realSeqList: #compare strings
            listOfEqualSeq.append(predictSeqObj)
    return listOfEqualSeq
   
def maxPointedSeq():
    max =  -1
    returnSeq = None
    for seq in listNodeSeq:
        a = len(((nodeSeq)(seq)).connedge)
        if a > max:
            returnSeq = seq
            max = a
    
    return returnSeq

def createArray(): # return array[seq][prog] = (freq of seq in prog) or 0 ( if connected)
    progLen = len(listNodeProg)
    seqLen = len(listNodeSeq)
    array = [[0 for i in range(progLen)] for j in range(seqLen)] #
    for i in range(0,seqLen):
        nodeSeq = listNodeSeq[i]
        for j in range (0,progLen):
            progNode = listNodeProg[j]
            for ed in (((nodeProg)(progNode)).connedge) :
                if ((Edge)(ed)).nodeprog.seq == progNode.seq :
                    array[i][j] = ((Edge)(ed)).freqInNode
    
    
    return array    
                                          
def buildModel(dirpath):
    for inputfile in os.listdir(dirpath):
        run(inputfile)
        
    pass

def testModel(inputfile):


     #dynamic seq....
     pass
    



  #  with open("workspace\\mythesis\\Thesis\\src\\xmlStructure.txt", 'r') as content_file:
  #      content = content_file.read()
  #  
  #  content = content.replace("\"", "")
  #  with open("workspace\\mythesis\\Thesis\\src\\NewxmlStructuretxt", 'a') as the_file:
        

   # array = [[0 for i in range(2)] for j in range(3)]
    #print (array)
#    exctractSeq('t3.txt', 300)


def createDataSet(filename):
    file = open("datasetGraph.txt",'a')
    countempty = 0
    with open((r"C:\\Users\\adipola\\Desktop\\thesis\\apiCallsDataset\\forTeiresias\\sequence\\"+filename), 'r') as f:
        for line in f:
            words = line.split()
            if countempty < 5:
                countempty+=1
                continue
            
            seq = ""
            for i in range(2,len(words)):
                    seq += words[i]+" "
            print(""+ filename+" ,"+  seq+"\n")
            writeToFile = ""+ filename+" ,"+seq+"\n"
            file.write(writeToFile)
    file.close()
    
def createSeqSet():
      #dir-path: C:\\Users\\Polak\\Desktop\\Documents\\university\\thesis\\apiCallsDataset\\forTeiresias\\sequence
    for filename in os.listdir(r"C:\\Users\\adipola\\Desktop\\thesis\\apiCallsDataset\\forTeiresias\\sequence"):
#C:\Users\adipola\Desktop\thesis\apiCallsDataset\forTeiresias\sequence
        countempty = 0
        seqSet = set()
        with open((r"C:\\Users\\adipola\\Desktop\\thesis\\apiCallsDataset\\forTeiresias\\sequence\\"+filename), 'r') as f:
            for line in f:
                words = line.split()
                if countempty < 5:
                    countempty+=1
                    continue
                seq = ""
                for i in range(2,len(words)):
                    seq += words[i]+" "
                seqSet.add(seq)
                
        with open("seqSet.txt",'a') as file :
             for elem in seqSet:
                 file.write(str(elem)+"\n")
             
         
        createDataSet(filename)


if __name__ == '__main__':
  pass


    